<template>
  <div class="container">
    <h2>Canvas模拟浏览器跨区域文本选择效果</h2>
    <div class="book-container">
      <canvas
        ref="canvasRef"
        class="book-canvas"
        width="600"
        height="400"
        @mousedown="handleCanvasMouseDown"
        @mousemove="handleCanvasMouseMove"
        @mouseup="handleCanvasMouseUp"
        @mouseleave="handleCanvasMouseUp"
      ></canvas>
    </div>
    
    <div class="controls" v-if="selectedText">
      <button @click="copyText">复制: "{{ selectedText }}"</button>
      <button @click="clearSelection">清除选择</button>
    </div>
    
    <div class="instructions">
      <p>模拟浏览器跨区域文本选择效果：</p>
      <ul>
        <li>支持跨页面区域连续选择文本</li>
        <li>模拟浏览器跨框架选择行为</li>
        <li>按照阅读顺序连续选择</li>
        <li>提供完整的文本选择体验</li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'

const canvasRef = ref<HTMLCanvasElement>()
const isSelecting = ref(false)
const selectionStartPos = ref<{x: number, y: number} | null>(null)
const selectionEndPos = ref<{x: number, y: number} | null>(null)

// 定义页面区域和文本（按阅读顺序排列）
const allCharacters = [
  // 左页文本
  { char: '春', x: 50, y: 50, width: 20, height: 25, page: 'left' },
  { char: '天', x: 75, y: 50, width: 20, height: 25, page: 'left' },
  { char: '来', x: 100, y: 50, width: 20, height: 25, page: 'left' },
  { char: '了', x: 125, y: 50, width: 20, height: 25, page: 'left' },
  { char: '，', x: 150, y: 50, width: 10, height: 25, page: 'left' },
  { char: '花', x: 50, y: 80, width: 20, height: 25, page: 'left' },
  { char: '儿', x: 75, y: 80, width: 20, height: 25, page: 'left' },
  { char: '开', x: 100, y: 80, width: 20, height: 25, page: 'left' },
  { char: '满', x: 125, y: 80, width: 20, height: 25, page: 'left' },
  { char: '园', x: 150, y: 80, width: 20, height: 25, page: 'left' },
  { char: '子', x: 50, y: 120, width: 20, height: 25, page: 'left' },
  { char: '，', x: 75, y: 120, width: 10, height: 25, page: 'left' },
  { char: '鸟', x: 100, y: 120, width: 20, height: 25, page: 'left' },
  { char: '儿', x: 125, y: 120, width: 20, height: 25, page: 'left' },
  { char: '唱', x: 150, y: 120, width: 20, height: 25, page: 'left' },
  { char: '歌', x: 175, y: 120, width: 20, height: 25, page: 'left' },
  
  // 右页文本
  { char: '夏', x: 350, y: 50, width: 20, height: 25, page: 'right' },
  { char: '日', x: 375, y: 50, width: 20, height: 25, page: 'right' },
  { char: '炎', x: 400, y: 50, width: 20, height: 25, page: 'right' },
  { char: '炎', x: 425, y: 50, width: 20, height: 25, page: 'right' },
  { char: '，', x: 450, y: 50, width: 10, height: 25, page: 'right' },
  { char: '绿', x: 350, y: 80, width: 20, height: 25, page: 'right' },
  { char: '树', x: 375, y: 80, width: 20, height: 25, page: 'right' },
  { char: '成', x: 400, y: 80, width: 20, height: 25, page: 'right' },
  { char: '荫', x: 425, y: 80, width: 20, height: 25, page: 'right' },
  { char: '，', x: 450, y: 80, width: 10, height: 25, page: 'right' },
  { char: '蝉', x: 350, y: 120, width: 20, height: 25, page: 'right' },
  { char: '鸣', x: 375, y: 120, width: 20, height: 25, page: 'right' },
  { char: '声', x: 400, y: 120, width: 20, height: 25, page: 'right' },
  { char: '声', x: 425, y: 120, width: 20, height: 25, page: 'right' }
]

const selectedText = computed(() => {
  if (!selectionStartPos.value || !selectionEndPos.value) return ''
  
  const selectedChars = getSelectedCharacters()
  return selectedChars.map(char => char.char).join('')
})

const draw = () => {
  if (!canvasRef.value) return
  const ctx = canvasRef.value.getContext('2d')
  if (!ctx) return
  
  // 清空画布
  ctx.clearRect(0, 0, canvasRef.value.width, canvasRef.value.height)
  
  // 绘制书籍背景
  ctx.fillStyle = '#f5f5dc'
  ctx.fillRect(0, 0, canvasRef.value.width, canvasRef.value.height)
  
  // 绘制页面分隔线
  ctx.strokeStyle = '#ccc'
  ctx.lineWidth = 2
  ctx.beginPath()
  ctx.moveTo(300, 0)
  ctx.lineTo(300, 400)
  ctx.stroke()
  
  // 绘制页面标题
  ctx.fillStyle = '#666'
  ctx.font = '14px sans-serif'
  ctx.fillText('左页', 20, 30)
  ctx.fillText('右页', 320, 30)
  
  // 绘制装订线效果
  ctx.strokeStyle = '#ddd'
  ctx.lineWidth = 1
  ctx.beginPath()
  ctx.moveTo(295, 0)
  ctx.lineTo(295, 400)
  ctx.moveTo(305, 0)
  ctx.lineTo(305, 400)
  ctx.stroke()
  
  // 绘制文字
  ctx.fillStyle = '#333'
  ctx.font = '18px sans-serif'
  ctx.textBaseline = 'top'
  
  allCharacters.forEach(char => {
    ctx.fillText(char.char, char.x, char.y)
  })
  
  // 绘制选择区域
  if (isSelecting.value && selectionStartPos.value && selectionEndPos.value) {
    drawSelection(ctx)
  } else if (selectionStartPos.value && selectionEndPos.value) {
    drawSelection(ctx)
  }
}

const drawSelection = (ctx: CanvasRenderingContext2D) => {
  if (!selectionStartPos.value || !selectionEndPos.value) return
  
  const selectedChars = getSelectedCharacters()
  
  // 为选中的字符绘制高亮
  ctx.fillStyle = 'rgba(30, 144, 255, 0.4)'
  selectedChars.forEach(char => {
    ctx.fillRect(char.x, char.y, char.width, char.height)
  })
  
  // // 绘制实时选择区域边框
  // if (isSelecting.value) {
  //   const startX = Math.min(selectionStartPos.value.x, selectionEndPos.value.x)
  //   const startY = Math.min(selectionStartPos.value.y, selectionEndPos.value.y)
  //   const endX = Math.max(selectionStartPos.value.x, selectionEndPos.value.x)
  //   const endY = Math.max(selectionStartPos.value.y, selectionEndPos.value.y)
    
  //   ctx.strokeStyle = 'rgba(30, 144, 255, 0.8)'
  //   ctx.lineWidth = 1
  //   ctx.setLineDash([5, 5])
  //   ctx.strokeRect(startX, startY, endX - startX, endY - startY)
  //   ctx.setLineDash([])
  // }
}

// 获取选中的字符
const getSelectedCharacters = () => {
  if (!selectionStartPos.value || !selectionEndPos.value) return []
  
  // 找到起点和终点对应的字符索引
  const startIndex = findClosestCharacterIndex(selectionStartPos.value)
  const endIndex = findClosestCharacterIndex(selectionEndPos.value)
  
  // 确定选择范围（包含中间的所有字符，按顺序）
  const start = Math.min(startIndex, endIndex)
  const end = Math.max(startIndex, endIndex)
  
  // 返回选中的字符数组
  const selectedChars = []
  for (let i = start; i <= end; i++) {
    selectedChars.push(allCharacters[i])
  }
  
  return selectedChars
}

// 找到最接近指定坐标的字符索引
const findClosestCharacterIndex = (pos: {x: number, y: number}) => {
  let closestIndex = 0
  let minDistance = Infinity
  
  allCharacters.forEach((char, index) => {
    const centerX = char.x + char.width / 2
    const centerY = char.y + char.height / 2
    
    const distance = Math.sqrt(
      Math.pow(pos.x - centerX, 2) + Math.pow(pos.y - centerY, 2)
    )
    
    if (distance < minDistance) {
      minDistance = distance
      closestIndex = index
    }
  })
  
  return closestIndex
}

const handleCanvasMouseDown = (e: MouseEvent) => {
  if (!canvasRef.value) return
  
  const rect = canvasRef.value.getBoundingClientRect()
  const x = e.clientX - rect.left
  const y = e.clientY - rect.top
  
  isSelecting.value = true
  selectionStartPos.value = { x, y }
  selectionEndPos.value = { x, y }
  
  draw()
}

const handleCanvasMouseMove = (e: MouseEvent) => {
  if (!isSelecting.value || !canvasRef.value) return
  
  const rect = canvasRef.value.getBoundingClientRect()
  const x = e.clientX - rect.left
  const y = e.clientY - rect.top
  
  selectionEndPos.value = { x, y }
  draw()
}

const handleCanvasMouseUp = () => {
  isSelecting.value = false
  draw()
}

const copyText = () => {
  const selectedChars = getSelectedCharacters()
  const text = selectedChars.map(char => char.char).join('')
  
  if (text) {
    navigator.clipboard.writeText(text)
      .then(() => {
        alert('文本已复制到剪贴板!')
      })
      .catch(err => {
        console.error('复制失败:', err)
      })
  }
}

const clearSelection = () => {
  selectionStartPos.value = null
  selectionEndPos.value = null
  draw()
}

onMounted(() => {
  draw()
})
</script>

<style scoped lang="less">
.container {
  padding: 20px;
  max-width: 1000px;
  margin: 0 auto;
}

.book-container {
  display: inline-block;
  border: 2px solid #8b4513;
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

.book-canvas {
  display: block;
  cursor: text;
}

.controls {
  margin: 15px 0;
  
  button {
    padding: 8px 16px;
    margin-right: 10px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    
    &:hover {
      background: #0056b3;
    }
  }
}

.instructions {
  margin-top: 20px;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 4px;
  
  ul {
    margin: 10px 0;
    padding-left: 20px;
  }
  
  li {
    margin: 5px 0;
  }
}
</style>